<template>
  <div class="note-edit">
    <div class="note-edit-tree">
      <div class="note-edit-tree-btns">
        <div class="net-btns-home" @click="handleGoBack">
          <svg-icon style="width: 16px; height: 16px;" icon-class="left" />
          <span>天晴在线笔记</span>
        </div>
        <div class="net-btns-title text-hidden2">{{ noteName }}</div>
        <div class="net-btns-search">
          <div @click="handleSearch">点击检索</div>
          <el-button class="net-btns-search-btn" plain icon="Plus" type="warning" @click="handleAdd"></el-button>
        </div>
      </div>
      <div class="note-edit-tree-wrap">
        <el-tree
            ref="artTreeRef"
            :data="treeData"
            draggable
            default-expand-all
            :props="treeProps"
            node-key="id"
            @node-drop="handleDrop"
            @current-change="handleCurrentChange"
            :expand-on-click-node="false"
            check-on-click-node
        >
          <template #default="{ node, data }">
          <span class="custom-tree-node">
            <span>{{ node.label }}</span>
            <span class="custom-tree-node-btns">
              <a @click.stop="moreClick(data)">
                <el-dropdown trigger="click">
                  <span class="el-dropdown-link">
                    <svg-icon style="width: 16px; height: 16px;" icon-class="moreOne" />
                  </span>
                  <template #dropdown>
                    <el-dropdown-menu>
                      <el-dropdown-item @click="handleUpdate(data)">重命名</el-dropdown-item>
                      <el-dropdown-item @click="handleGoEdit(data)">编辑</el-dropdown-item>
                      <el-dropdown-item @click="handleDelete(data)">删除</el-dropdown-item>
                    </el-dropdown-menu>
                  </template>
                </el-dropdown>
              </a>
              <a @click.stop="addNode(data)" style="margin-left: 2px">
                <svg-icon style="width: 16px; height: 16px;" icon-class="plus" />
              </a>
            </span>
          </span>
          </template>
        </el-tree>
      </div>
    </div>
    <div class="note-edit-wrap">
      <div class="new-head">
        <div class="new-head-title">
          <span>{{ currentArt.artTitle }}</span>
          <div @click="handleUpdateTitle(data)" style="margin-left: 10px; cursor: pointer;">
            <svg-icon style="width: 14px; height: 14px;" icon-class="edit" />
          </div>
        </div>
        <div class="new-head-btns">
          <el-button v-if="!editFlag" type="primary" plain @click="handleOpenEdit">编辑</el-button>
          <el-button v-else type="success" plain @click="handleSaveArt">保存</el-button>
          <el-button v-if="editFlag" type="danger" plain @click="handleExitEdit">退出编辑</el-button>
        </div>
      </div>
      <div class="new-body" ref="editorRef">
        <div class="aie-container">
          <div v-show="editFlag" class="aie-header">
            <div class="aie-container-header"></div>
          </div>
          <div :class="['aie-container-panel', editFlag ? 'aie-container-panel-edit' : '']">
            <div class="aie-container-main-wrap">
              <div class="aie-container-main"></div>
            </div>
          </div>
          <div v-show="editFlag" class="aie-container-footer"></div>
        </div>
      </div>
    </div>
    <!-- 添加或修改文章管理对话框 -->
    <el-dialog :title="title" v-model="open" width="500px" append-to-body>
      <el-form ref="articleRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="目录" prop="pid">
          <el-tree-select
              v-model="form.pid"
              :data="artOptions"
              :props="{ value: 'id', label: 'artTitle', children: 'children' }"
              value-key="id"
              placeholder="请选择所属目录"
              check-strictly
          />
        </el-form-item>
        <el-form-item label="标题" prop="artTitle">
          <el-input v-model="form.artTitle" placeholder="请输入文章标题"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="cancel">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup name="NoteEdit">
import {AiEditor} from "aieditor";
import "aieditor/dist/style.css";
import { ElNotification } from 'element-plus'
import {getArticle, delArticle, addArticle, updateArticle, getArticleTree} from "@/api/arts";
import { getToken } from "@/utils/auth";

import {useRoute, useRouter} from "vue-router";
import {moveArticle} from "../../../api/arts.js";

// oss存储信息
const publicFileUrl = import.meta.env.VITE_APP_PUBLIC_FILE_URL;
const bucketName = import.meta.env.VITE_APP_PUBLIC_FILE_BUCKET;

const {proxy} = getCurrentInstance();

const router = useRouter();
const route = useRoute();

const {noteId, noteName} = route.query;

const artTreeRef = ref(null);

const treeData = ref([]);
const artOptions = ref([]);
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");

const data = reactive({
  form: {},
  queryParams: {
    pid: null,
    noteId: noteId,
    artTitle: null,
    artContent: null,
  },
  rules: {}
});

const {queryParams, form, rules} = toRefs(data);

const currentArt = ref({});

const editorRef = ref(null);
let aiEditor = null;

const editFlag = ref(false);

const treeProps = {
  children: 'children',
  label: 'artTitle',
}

// 取消按钮
function cancel() {
  open.value = false;
  reset();
}

// 表单重置
function reset() {
  form.value = {
    id: null,
    pid: null,
    noteId: noteId,
    artTitle: null,
    artContent: null,
    createTime: null,
    createBy: null,
    updateTime: null,
    updateBy: null,
    delFlag: null
  };
  proxy.resetForm("articleRef");
}

/** 新增按钮操作 */
function handleAdd() {
  reset();
  open.value = true;
  title.value = "创建文章";
}

/** 修改按钮操作 */
function handleUpdate(row) {
  reset();
  const _id = row.id || ids.value
  getArticle(_id).then(response => {
    // 这个地方调整
    form.value = response.data;
    open.value = true;
    title.value = "修改文章";
  });
}

function handleUpdateTitle() {
  handleUpdate(currentArt.value);
}

/** 提交按钮 */
function submitForm() {
  proxy.$refs["articleRef"].validate(valid => {
    if (valid) {
      if (form.value.id != null) {
        form.value.artContent = null;
        updateArticle(form.value).then(response => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          getArtTree();
        });
      } else {
        addArticle(form.value).then(response => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          getArtTree();
        });
      }
    }
  });
}

/** 删除按钮操作 */
function handleDelete(row) {
  proxy.$modal.confirm('是否确认删除文章:"' + row.artTitle + '"？').then(function () {
    return delArticle(row.id);
  }).then(() => {
    getArtTree();
    proxy.$modal.msgSuccess("删除成功");
  }).catch(() => {
  });
}


/** 初始化文章树 */
const getArtTree = () => {
  // 查询文章树
  getArticleTree({noteId: noteId}).then(res => {
    if (res.code === 200) {
      treeData.value = res.data;
      artOptions.value = [{ id: '0', artTitle: '主目录', children: res.data }];
      if (res.data && res.data.length > 0) {
        if (!currentArt.value || !currentArt.value.id) {
          currentArt.value = res.data[0];
        }
        // 延时一会儿，等树渲染完成
        setTimeout(() => {
          proxy.$refs.artTreeRef.setCurrentKey(currentArt.value.id, true);
        }, 300)
      }
    }
  })
}

/** 节点选中触发 */
const handleCurrentChange = (row) => {
  getArticle(row.id).then(response => {
    // 这个地方调整
    currentArt.value = response.data;
    // 这组件有bug -- 😔
    if (!editFlag.value) {
      aiEditor.setEditable(true);
    }
    aiEditor.clear();
    aiEditor.setContent(currentArt.value.artContent);
    if (!editFlag.value) {
      aiEditor.setEditable(false);
    }
  });
}

const handleDrop = (draggingNode, dropNode, dropType, ev) => {
  const data = {
    sourceId: draggingNode.data.id,
    targetId: dropNode.data.id,
    sort: dropType
  }
  moveArticle(data).then(res => {
    if (res.code === 200) {
      getArtTree();
      proxy.$modal.msgSuccess("移动成功");
    }
  })
}

const initData = () => {
  getArtTree();
}

const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadImgUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 上传的图片服务器地址\
const headers = ref({ Authorization: "Bearer " + getToken() });

const handleSaveArt = () => {
  const content = aiEditor.getHtml();
  currentArt.value.artContent = content;
  const data = {
    id: currentArt.value.id,
    artContent: content
  }
  updateArticle(data).then(response => {
    if (response.code === 200) {
      proxy.$modal.msgSuccess("修改成功");
      open.value = false;
    }
  }).catch(err => {
    console.log(err, '222')
  });
}

function disSaveKey(event) {
  // 检查按键是否为Ctrl和S
  if (event.ctrlKey && event.key === 's') {
    // 阻止默认行为，即不执行保存操作
    event.preventDefault();
    console.log('Ctrl + S has been intercepted.');
  }
}

onMounted(() => {
  aiEditor = new AiEditor({
    element: editorRef.value,
    toolbarKeys: ["undo", "redo", "brush", "eraser",
      "|", "heading", "font-family", "font-size",
      "|", "bold", "italic", "underline", "strike", "link", "code", "subscript", "superscript", "hr", "todo", "emoji",
      "|", "highlight", "font-color",
      "|", "align", "line-height",
      "|", "bullet-list", "ordered-list", "indent-decrease", "indent-increase", "break",
      "|", "image", "video", "attachment", "quote", "code-block", "table",
      // "|", "source-code", "printer"
      "|", "printer"
    ],
    placeholder: "点击输入内容...",
    content: currentArt.value.artContent,
    editable: false,
    image: {
      allowBase64: true,
      defaultSize: 350,
      uploadUrl: uploadImgUrl.value,
      uploadFormName: "file", //上传时的文件表单名称
      uploadHeaders: headers.value,
      uploaderEvent: {
        onUploadBefore: (file, uploadUrl, headers) => {
          //监听图片上传之前，此方法可以不用回任何内容，但若返回 false，则终止上传
        },
        onSuccess: (file, response) => {
          //监听图片上传成功
          //注意：
          // 1、如果此方法返回 false，则图片不会被插入到编辑器
          // 2、可以在这里返回一个新的 json 给编辑器
          if (response.code === 200) {
            let url = publicFileUrl + '/' + bucketName + '/' + response.data.fileName;
            const res = {
              errorCode: 0,
              data: {
                src: url,
                alt: "www.tancire.com",
                align: 'center'
              }
            }
            return res;
          }
          return false;
        },
        onFailed: (file, response) => {
          //监听图片上传失败，或者返回的 json 信息不正确
        },
        onError: (file, error) => {
          //监听图片上传错误，比如网络超时等
        },
      },
      bubbleMenuItems: ["AlignLeft", "AlignCenter", "AlignRight", "delete"]
    },
    onSave: () => {
      setTimeout(() => {
        handleSaveArt();
      }, 100)
    }
  })
  editFlag.value = false;
  // 拦截ctrl + s
  document.addEventListener('keydown', disSaveKey);
})

onUnmounted(() => {
  aiEditor && aiEditor.destroy();
  // 取消拦截ctrl + s
  document.removeEventListener('keydown', disSaveKey);
})

const addNode = (data) => {
  reset();
  form.value.pid = data.id;
  open.value = true;
  title.value = "创建文章";
}

const removeNode = (data) => {
  console.log(data, '2222')
}

/** 更多按钮点击触发 */
const moreClick = () => {
  // btnsStyle.value[data.id].display = 'block';
}

const handleGoBack = () => {
  router.back();
}

const handleOpenEdit = () => {
  aiEditor.setEditable(true);
  editFlag.value = true;
}

const handleGoEdit = (data) => {
  currentArt.value = data;
  // 延时一会儿，等树渲染完成
  setTimeout(() => {
    proxy.$refs.artTreeRef.setCurrentKey(currentArt.value.id, true);
  }, 300)
  handleOpenEdit();
}

const handleExitEdit = () => {
  aiEditor.setEditable(false);
  editFlag.value = false;
}

/** 检索 */
const handleSearch = () => {
  ElNotification({
    title: '功能提醒',
    message: '检索功能暂未实现，定制开发可联系《天晴网络科技工作室》，官方网站地址：www.tancire.com',
    type: 'success',
  })
}

initData();
</script>

<style lang="scss" scoped>
.note-edit {
  display: flex;
  height: 100vh;
  overflow: hidden;

  &-tree {
    width: 260px;
    border-right: 1px solid #f2f2f2;
    overflow-y: auto;

    &-btns {
      padding: 10px 10px 0 10px;

      .net-btns-home {
        font-size: 14px;
        color: var(--tc-title-color-dan);
        display: flex;
        align-items: center;
        cursor: pointer;
        user-select: none;

        > span {
          margin-left: 4px;
        }
      }

      .net-btns-title {
        font-size: 16px;
        color: var(--tc-title-color);
        font-weight: 600;
        margin-top: 10px;
      }

      .net-btns-search {
        display: flex;
        align-items: center;
        margin-top: 10px;

        > div {
          height: 32px;
          flex: 1;
          cursor: pointer;
          border: 1px solid var(--tc-primary);
          line-height: 32px;
          padding: 0 6px;
          border-radius: 4px;
          font-size: 14px;
          color: var(--tc-title-color-dan);
        }

        &-btn {
          margin-left: 6px;
          padding: 8px 10px;
          border-color: var(--tc-primary);
        }

      }

    }

    &-wrap {
      padding: 10px;

      .custom-tree-node {
        display: flex;
        align-items: center;
        justify-content: space-between;
        flex: 1;
        width: 0;
        padding-right: 4px;

        &-btns {
          display: none;

          a {
            padding: 4px;
            border-radius: 4px;
          }

          a:hover {
            background-color: var(--tc-tree-node-hover-bgc);
          }
        }
      }

      .custom-tree-node:hover {

        .custom-tree-node-btns {
          display: block;
        }
      }

      .custom-tree-node:focus {

        .custom-tree-node-btns {
          display: block;
        }
      }

      :deep(.el-tree) {
        font-size: var(--tc-tree-font-size-base);
        color: var(--tc-title-color);

        .el-tree-node {

          .el-tree-node__content {
            height: 34px;
            border-radius: 4px;
          }

          .el-tree-node__children {

            .el-tree-node.is-current {

              > .el-tree-node__content {
                background-color: var(--tc-bgc-primary);
                border-radius: 4px;
                color: var(--tc-white);

                .el-icon {
                  color: var(--tc-white);
                }
              }
            }
          }
        }

        .el-tree-node.is-current {

          > .el-tree-node__content {
            background-color: var(--tc-bgc-primary);
            border-radius: 4px;
            color: var(--tc-white);

            .el-icon {
              color: var(--tc-white);
            }
          }
        }
      }
    }
  }

  &-wrap {
    flex: 1;

    .new-head {
      height: 40px;
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding: 0 20px;

      &-title {
        font-size: 16px;
        color: var(--tc-title-color);
        font-weight: 600;
        display: flex;
        align-items: center;
      }
    }


    .aie-container {
      position: relative;

      .aie-header {
        display: flex;
        align-items: center;
        justify-content: center;

        .aie-container-header {

          :deep(.aie-container) aie-header>div {
            border: none;
          }
        }
      }

      .aie-container-panel {
        background-color: #f2f2f2;
        height: calc(100vh - 40px);
        overflow-y: auto;

        .aie-container-main-wrap {
          margin: 10px auto;
          width: 800px;
          min-height: 1200px;
          background-color: #ffffff;
          padding: 10px;

          .aie-container-main {

          }
        }
      }

      .aie-container-panel-edit {
        height: calc(100vh - 98px);
      }

      .aie-container-footer {

      }
    }
  }
}
</style>
